#include "cgzCHttpC.h"
#include "cgzCThreadPool.h"

cgzCHttpLoopC::cgzCHttpLoopC()
    : m_cmd(HTTPC_LOOP)
{
}

cgzCHttpLoopC::~cgzCHttpLoopC()
{
}

cgzCHttpExecC::cgzCHttpExecC(long cookid)
    : m_cookid(cookid)
{
}

cgzCHttpExecC::~cgzCHttpExecC()
{
}

cgzCHttpGetC::cgzCHttpGetC(
    long cookid, const char *url, 
    const char *uri, 
    const std::map<std::string, std::string> &headers,
    const char* body)
    : cgzCHttpExecC(cookid),
      m_url(url),
      m_uri(uri),
      m_body(body),
      m_headers(std::move(headers))
{
    m_cmd = HTTPC_GET;
}

cgzCHttpGetC::~cgzCHttpGetC()
{
}

cgzCHttpPostC::cgzCHttpPostC(
    long cookid, const char *url,
     const char *uri, 
     const std::map<std::string, std::string> &headers,
     const char* body)
    : cgzCHttpExecC(cookid),
      m_url(url),
      m_uri(uri),
      m_body(body),
      m_headers(std::move(headers))
{
    m_cmd = HTTPC_POST;
}

cgzCHttpPostC::~cgzCHttpPostC()
{
}

cgzCHttpPutC::cgzCHttpPutC(
    long cookid, 
    const char *url, 
    const char *uri, 
    const std::map<std::string, std::string> &headers,
    const char* body)
    : cgzCHttpExecC(cookid),
      m_url(url),
      m_uri(uri),
      m_body(body),
      m_headers(std::move(headers))
{
    m_cmd = HTTPC_PUT;
}

cgzCHttpPutC::~cgzCHttpPutC()
{
}

cgzCHttpDeleteC::cgzCHttpDeleteC(
    long cookid, 
    const char *url, 
    const char *uri, 
    const std::map<std::string, std::string> &headers,
    const char* body)
    : cgzCHttpExecC(cookid),
      m_url(url),
      m_uri(uri),
      m_body(body),
      m_headers(std::move(headers))
{
    m_cmd = HTTPC_DELETE;
}

cgzCHttpDeleteC::~cgzCHttpDeleteC()
{
}

cgzCHttpHeadC::cgzCHttpHeadC(
    long cookid, 
    const char *url, 
    const char *uri, 
    const std::map<std::string, std::string> &headers,
    const char* body)
    : cgzCHttpExecC(cookid),
      m_url(url),
      m_uri(uri),
      m_body(body),
      m_headers(std::move(headers))
{
    m_cmd = HTTPC_HEAD;
}

cgzCHttpHeadC::~cgzCHttpHeadC()
{
}

cgzCHttpOptionsC::cgzCHttpOptionsC(
    long cookid, 
    const char *url, 
    const char *uri, 
    const std::map<std::string, std::string> &headers,
    const char* body)
    : cgzCHttpExecC(cookid),
      m_url(url),
      m_uri(uri),
      m_body(body),
      m_headers(std::move(headers))
{
    m_cmd = HTTPC_OPTIONS;
}

cgzCHttpOptionsC::~cgzCHttpOptionsC()
{
}

cgzCHttpC::cgzCHttpC(cgzCThreadPool *pool, const char *name, int cid)
    : cgzITask(pool, name, cgzETask::CHttpC),
      m_cid(cid)
{
    pool->addTask(m_name.c_str(), this);
}

cgzCHttpC::~cgzCHttpC()
{
}

bool cgzCHttpC::run(int64_t nms)
{
    while (!m_runTask.empty())
    {
        auto task = static_cast<cgzCHttpLoopC *>(m_runTask.front());
        m_runTask.pop_front();
        if (HTTPC_LOOP == task->m_cmd)
        {
            assert(false);
            continue;
        }

        switch (task->m_cmd)
        {
        case HTTPC_GET:
            exec(static_cast<cgzCHttpGetC *>(task));
            break;
        case HTTPC_POST:
            exec(static_cast<cgzCHttpPostC *>(task));
            break;
        case HTTPC_PUT:
            exec(static_cast<cgzCHttpDeleteC *>(task));
            break;
        case HTTPC_DELETE:
            exec(static_cast<cgzCHttpHeadC *>(task));
            break;
        case HTTPC_HEAD:
            exec(static_cast<cgzCHttpOptionsC *>(task));
            break;
        case HTTPC_OPTIONS:
            exec(static_cast<cgzCHttpOptionsC *>(task));
            break;
        default:
            break;
        }
    }

    // 检测
    while (!m_waits.empty())
    {
        auto current_task = m_waits.front();
        if (current_task.is_done())
        {
            m_waits.pop();
        }
        else
        {
            break;
        }
    }

    m_runms = nms + 5;
    return true;
}

void cgzCHttpC::exec(cgzCHttpGetC *exec)
{
    // 创建 HTTP 客户端
    http_client client(U(exec->m_url));
    // 创建 GET 请求
    uri_builder builder(U(exec->m_uri)); // 请求的 URI
    auto request_uri = builder.to_uri().to_string();

    for (auto &header : exec->m_headers)
    {
        builder.append_query(header.first, header.second);
    }

    auto body = json::value::parse(exec->m_body);

    // 发送请求并处理响应
    m_waits.push(client.request(methods::GET, request_uri, body)
                     .then([](http_response response)
                           {
                               // 检查响应状态
                               auto code = response.status_code();
                               if (code == status_codes::Created || code == status_codes::OK)
                               {
                                   // 读取响应体
                                   return response.extract_json();
                               }
                               return pplx::task_from_result(json::value()); // 返回空 JSON
                           })
                     .then([this, exec](json::value jsonValue)
                           {
                               // 处理 JSON 响应
                               exec->m_ret = jsonValue;
                               exec->origin = m_id;
                               exec->target = m_cid;
                               retTask(exec); }));
}
void cgzCHttpC::exec(cgzCHttpPostC *exec)
{
    // 创建 HTTP 客户端
    http_client client(U(exec->m_url));

    // 创建 POST 请求
    uri_builder builder(U(exec->m_uri)); // 请求的 URI
    auto request_uri = builder.to_uri().to_string();
    for (auto &header : exec->m_headers)
    {
        builder.append_query(header.first, header.second);
    }
    auto body = json::value::parse(exec->m_body);

    // 发送请求并处理响应
    m_waits.push(client.request(methods::POST, request_uri, body)
                     .then([](http_response response)
                           {
                               // 检查响应状态
                               auto code = response.status_code();
                               if (code == status_codes::Created || code == status_codes::OK)
                               {
                                   // 读取响应体
                                   return response.extract_json();
                               }
                               return pplx::task_from_result(json::value()); // 返回空 JSON
                           })
                     .then([this, exec](json::value jsonValue)
                           {
                               // 处理 JSON 响应
                               exec->m_ret = jsonValue;
                               exec->origin = m_id;
                               exec->target = m_cid;
                               retTask(exec); }));
}
void cgzCHttpC::exec(cgzCHttpPutC *exec)
{
    // 创建 HTTP 客户端
    http_client client(U(exec->m_url));

    // 创建 PUT 请求
    uri_builder builder(U(exec->m_uri)); // 请求的 URI
    auto request_uri = builder.to_uri().to_string();
    for (auto &header : exec->m_headers)
    {
        builder.append_query(header.first, header.second);
    }

    auto body = json::value::parse(exec->m_body);

    // 发送请求并处理响应
    m_waits.push(client.request(methods::PUT, request_uri, body)
                     .then([](http_response response)
                           {
                               // 检查响应状态
                                auto code = response.status_code();
                                if (code == status_codes::Created || code == status_codes::OK)
                                {
                                    // 读取响应体
                                    return response.extract_json();
                                }
                               return pplx::task_from_result(json::value()); // 返回空 JSON
                           })
                     .then([this, exec](json::value jsonValue)
                           {
                               // 处理 JSON 响应
                               exec->m_ret = jsonValue;
                               exec->origin = m_id;
                               exec->target = m_cid;
                               retTask(exec); }));
}
void cgzCHttpC::exec(cgzCHttpDeleteC *exec)
{
    // 创建 HTTP 客户端
    http_client client(U(exec->m_url));

    // 创建 DEL 请求
    uri_builder builder(U(exec->m_uri)); // 请求的 URI
    auto request_uri = builder.to_uri().to_string();
    for (auto &header : exec->m_headers)
    {
        builder.append_query(header.first, header.second);
    }

    auto body = json::value::parse(exec->m_body);

    // 发送请求并处理响应
    m_waits.push(client.request(methods::DEL, request_uri, body)
                     .then([](http_response response)
                           {
                               // 检查响应状态
                               auto code = response.status_code();
                               if (code == status_codes::Created || code == status_codes::OK)
                               {
                                   // 读取响应体
                                   return response.extract_json();
                               }
                               return pplx::task_from_result(json::value()); // 返回空 JSON
                           })
                     .then([this, exec](json::value jsonValue)
                           {
                               // 处理 JSON 响应
                               exec->m_ret = jsonValue;
                               exec->origin = m_id;
                               exec->target = m_cid;
                               retTask(exec); 
                               }));
}
void cgzCHttpC::exec(cgzCHttpHeadC *exec)
{
    // 创建 HTTP 客户端
    http_client client(U(exec->m_url));

    // 创建 HEAD 请求
    uri_builder builder(U(exec->m_uri)); // 请求的 URI
    auto request_uri = builder.to_uri().to_string();
    for (auto &header : exec->m_headers)
    {
        builder.append_query(header.first, header.second);
    }

    auto body = json::value::parse(exec->m_body);

    // 发送请求并处理响应
    m_waits.push(client.request(methods::HEAD, request_uri, body)
                     .then([this, exec](http_response response)
                           {
                               auto js = json::value::object();
                               js[U("status")] = json::value::number(response.status_code());

                               exec->m_ret = js;
                               exec->origin = m_id;
                               exec->target = m_cid;
                               retTask(exec); }));
}
void cgzCHttpC::exec(cgzCHttpOptionsC *exec)
{
    // 创建 HTTP 客户端
    http_client client(U(exec->m_url));

    // 创建 OPTIONS 请求
    uri_builder builder(U(exec->m_uri)); // 请求的 URI
    auto request_uri = builder.to_uri().to_string();
    for (auto &header : exec->m_headers)
    {
        builder.append_query(header.first, header.second);
    }

    auto body = json::value::parse(exec->m_body);

    // 发送请求并处理响应
    client.request(web::http::methods::OPTIONS, request_uri, body)
        .then([this, exec](web::http::http_response response)
              {
                // 你可以检查允许的方法
                auto js = json::value::object();
                auto allowHeader = response.headers().find(U("Allow"));
                if (allowHeader != response.headers().end())
                {
                   js[U("allowed_methods")] = web::json::value::string(allowHeader->second);
                }
                js[U("status_code")] = web::json::value::number(response.status_code());
                exec->m_ret = js;
                exec->origin = m_id;
                exec->target = m_cid;
                retTask(exec); });
}